package com.pc.scrs.filter;

import com.pc.scrs.service.impl.LoginDetailService;
import com.pc.scrs.utils.JwtUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * jwt请求过滤器
 */
@Component
public class JwtFilter extends OncePerRequestFilter {

    @Resource
    private LoginDetailService loginDetailService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication != null) {
            filterChain.doFilter(request, response);
            return;
        }

        // 获得请求中的token信息,jwtToken为请求头中携带的token名称
        String jwtStr = request.getHeader("jwtToken");
        if(StringUtils.isEmpty(jwtStr)){
            //请求中没有token
            filterChain.doFilter(request, response);
            return;
        }
        // 请求中有token信息，但token非法
        if(!JwtUtils.verify(jwtStr)){
            filterChain.doFilter(request, response);
            return;
        }

        // 请求中有token信息，且token合法,就从请求中获取携带的token，
        // 然后转为Spring Security的Authentication Token(需要带有用户所有的权限),保存在Spring Security上下文中

        //获得token中的username
        String username=JwtUtils.getUserNameFormJwt(jwtStr);
        //调用登录查询方法，获得Spring Security的UserDetails认证对象
        UserDetails userDetails=loginDetailService.loadUserByUsername(username);
        UsernamePasswordAuthenticationToken authenticationToken=
                new UsernamePasswordAuthenticationToken(
                        userDetails.getUsername(),
                        userDetails.getPassword(),
                        userDetails.getAuthorities());

        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        filterChain.doFilter(request, response);//放行到下一个过滤器
    }
}
